<?php

namespace App\Listeners;

use App\Constants\PaymentBusinessScene;
use App\Constants\Queue;
use App\Services\Java\ApiService;
use App\Services\PosApi\Order;
use D1M\Payment\Contracts\CombinedPaymentRepositoryInterface;
use D1M\Payment\Models\Payment as PaymentModel;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Log;
use Throwable;

/**
 * 通知 ES 系统订单支付状态变了
 */
abstract class NotifyOrderPaymentStatusChanged implements ShouldQueue
{

    /**
     * The name of the connection the job should be sent to.
     *
     * @var string|null
     */
    public $connection = 'redis-enhanced';

    /**
     * The name of the queue the job should be sent to.
     *
     * @var string|null
     */
    public $queue = Queue::PAYMENT_RESULT_NOTIFY_ES;

    /**
     * 发生异常时的重试次数
     *
     * @var int
     */
    public $tries = 8;

    /**
     * 发生异常时的重试间隔时间
     *
     * 间隔：3s、9s、1m、5m、30m、1h、6h、12h
     *
     * @var array
     */
    public $backoff = [3, 9, 60, 300, 1800, 3600, 21600, 43200];

    private CombinedPaymentRepositoryInterface $combinedPaymentRepository;

    private ApiService $esService;

    /**
     * @param CombinedPaymentRepositoryInterface $combinedPaymentRepository
     * @param ApiService $esService
     */
    public function __construct(
        CombinedPaymentRepositoryInterface $combinedPaymentRepository,
        ApiService $esService
    )
    {
        $this->combinedPaymentRepository = $combinedPaymentRepository;
        $this->esService = $esService;
    }

    /**
     * 处理订单支付状态变更
     *
     * @param int $id 组合支付单 ID
     * @param string $state 支付状态。这个是 ES 系统定义的接口参数，值由他们定义。
     * @param string $label 支付状态描述性文本
     * @throws Throwable
     */
    protected function doHandle(int $id, string $state, string $label)
    {
        $combinedPayment = $this->combinedPaymentRepository->getById($id);
        if ($combinedPayment->getBusinessScene() != PaymentBusinessScene::PLACING_ORDER) {
            return;
        }

        Log::info("POS项目订单{$label}，即将通知 ES 。组合支付单 ID：{$id}");

        $url = '/pay/api/order/pay-success';
        $payment = PaymentModel::where('combined_payment_id', $id)->where('batch', $combinedPayment->getBatch())->first();

        $data = [
            'no' => $combinedPayment->getBusinessOrderNo(),
            'payState' => $state,
            'payChannel' => $payment->payment_method,
        ];

        try {
            $this->esService->requestJava($url, $data, 'post');
        } catch (Throwable $e) {
            Log::error("订单{$label}回调，请求 ES 系统发生错误，错误消息："
                . $e->getMessage() . '，组合支付单 ID：' . $id);

            throw $e;
        }

        Log::info("订单{$label}，已通知 ES 。组合支付单 ID：{$id}");
    }

}